//
//  Network+API.m
//  YanXiuWang
//
//  Created by 招利 李 on 16/11/17.
//  Copyright © 2016年 小分队. All rights reserved.
//

#import "Network+General.h"
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#import "LCdes.h"
#import "UIImageGifView.h"
#import "NetworkManager+UINet.h"
@interface ReloadMaker : NSObject {
    @package
    __weak __kindof UIView *_containerView;
    __weak __kindof UIView *_mask;
    __kindof RequestNormal *_request;
    OnSuccess _successBlock;
    UIColor *_color;
    int _style;
    NSString *_text;
}

@end

@implementation ReloadMaker

- (void)dealloc {
    [_containerView removeFromSuperview];
    _request = nil;
    _successBlock = nil;
}

@end


@implementation GIFMaker {
    @package
    __weak __kindof RequestNormal *_request;
    __weak __kindof NSObject *_obj;
    __weak __kindof UIImageGifView *_gif;
    __weak __kindof UIView *_mask;
    UIColor *_color;
    int _style;
    NSString *_text;
    ReloadMaker *_reloadMaker;
}

- (FailStateReload)hasReloadOnFail {
    return ^(BOOL failNeedReload){
        if (_reloadMaker == nil && failNeedReload) {
            _reloadMaker = [ReloadMaker new];
        } else if (!failNeedReload) {
            _reloadMaker = nil;
        }
        return self;
    };
}

- (GIFStateView)maskView {
    return ^(UIView *view){
        _mask = view;
        return self;
    };
}

- (GIFStateText)withText {
    return ^(NSString *text){
        _text = text;
        return self;
    };
}

- (GIFStateColor)backgroundColor {
    return ^(UIColor *color){
        _color = color;
        return self;
    };
}

- (GIFStateObject)inObject {
    return ^(NSObject *obj) {
        _obj = obj;
        return _request;
    };
}

- (void)dealloc {
    [_gif imageGifEnd];
    [_gif removeFromSuperview];
    print(@"maker ----> 移除");
}

@end

@interface NSObject (NetStateProperty)

@property (nonatomic, assign) NetState state;
@property (nonatomic, strong) GIFMaker *maker;
@property (nonatomic, strong) ReloadMaker *reloader;

@end

@implementation NSObject (NetStateProperty)

- (void)cancelRequest:(UIButton *)button {
    
    GIFMaker *maker = self.maker;
    
    ReloadMaker *reloader;
    if (maker == nil) {
        reloader = self.reloader;
    } else {
        reloader = maker->_reloadMaker;
        self.reloader = reloader;
    }
    reloader->_request = nil;
    reloader->_successBlock = nil;
    [button.superview removeFromSuperview];
    self.reloader = nil;
    
}

- (void)reloadRequest:(UIButton *)button {
    ReloadMaker *reloader = (ReloadMaker *)button.weakTag;
    RequestNormal *request = reloader->_request;
    OnSuccess onSuccessBlock = reloader->_successBlock;
    
    [button.superview removeFromSuperview];
    
//    [request.showGIF(reloader->_style)
//     .backgroundColor(reloader->_color)
//     .maskView(reloader->_mask)
//     .hasReloadOnFail(YES)
//     .inObject(self)
//     onSuccess:onSuccessBlock];
    //天娃项目使用，其他项目换回之前的代码
    
    [request.showGIF(reloader->_style)
     .backgroundColor(reloader->_color)
     .maskView(reloader->_mask)
     .hasReloadOnFail(YES)
     .inObject(self)
     onTWSuccess:onSuccessBlock];
    self.reloader = nil;
}

- (void)showNetFailReloadViewOnRequest:(RequestNormal *)request onSuccess:(OnSuccess _Nonnull)successBlock {
    GIFMaker *maker = self.maker;
    
    ReloadMaker *reloader;
    if (maker == nil) {
        reloader = self.reloader;
    } else {
        reloader = maker->_reloadMaker;
        self.reloader = reloader;
    }
    
    if (reloader == nil) return;
    
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    
    UIView *view = reloader->_containerView;
    
    if (view == nil) {
        view = [[NSBundle mainBundle] loadNibNamed:@"NetFailReload" owner:nil options:nil].firstObject;
        view.tag = 76543;
        reloader->_containerView = view;
    }
    
    UIButton *button = [view viewWithTag:34567];
    reloader->_request = request;
    reloader->_successBlock = successBlock;
    
    button.weakTag = reloader;
    
    [button addTarget:self action:@selector(reloadRequest:) forControlEvents:UIControlEventTouchUpInside];
    /********/
    UIButton *buttonCancel = [view viewWithTag:34568];
    buttonCancel.weakTag = reloader;
    
    [buttonCancel addTarget:self action:@selector(cancelRequest:) forControlEvents:UIControlEventTouchUpInside];
    /********/
    UIView *mask = reloader->_mask;
    if (mask == nil) {
        
    } else if ([mask isKindOfClass:UIScrollView.class]) {
        view.frame = mask.frame;
        [mask.superview addSubview:view];
    } else {
        view.frame = mask.bounds;
        view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [mask addSubview:view];
    }

    [CATransaction commit];
}

- (void)setMaker:(GIFMaker *)maker {
    objc_setAssociatedObject(self, "gif.net.maker", maker, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (GIFMaker *)maker {
    return objc_getAssociatedObject(self, "gif.net.maker");
}

- (void)setReloader:(ReloadMaker *)reloader {
    objc_setAssociatedObject(self, "reload.net.maker", reloader, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (ReloadMaker *)reloader {
    return objc_getAssociatedObject(self, "reload.net.maker");
}

- (void)setState:(NetState)state {
    objc_setAssociatedObject(self, "obj.net.state", @(state), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    if (state == NetStateLoading) {
        GIFMaker *maker = self.maker;
        if (maker == nil) return;

        UIImageGifView *gif = objc_getAssociatedObject(self, "gif.net.view");
        if (gif != nil) {
            [gif imageGifEnd];
            [gif removeFromSuperview];
            maker->_gif = nil;
            objc_setAssociatedObject(self, "gif.net.view", nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
        gif = [[UIImageGifView alloc] init];
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        if (maker->_mask == nil) {
            [gif imageGif:maker->_style color:maker->_color text:maker->_text];
        } else if ( maker->_mask.superview == nil) {
            [gif imageGif:maker->_style color:maker->_color text:maker->_text frame:maker->_mask.bounds superView:maker->_mask];
        } else {
            [gif imageGif:maker->_style color:maker->_color text:maker->_text frame:maker->_mask.frame superView:maker->_mask.superview];
        }
        [CATransaction commit];
        maker->_gif = gif;
        objc_setAssociatedObject(self, "gif.net.view", gif, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    } else {
        __weak typeof(self) weakSelf = self;
        thread_main_after(0.25, ^{
            if (weakSelf.state == NetStateLoading) return;
            UIImageGifView *gif = objc_getAssociatedObject(weakSelf, "gif.net.view");
            [gif imageGifEnd];
            [gif removeFromSuperview];
            objc_setAssociatedObject(self, "gif.net.view", nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
            objc_setAssociatedObject(self, "obj.net.state", nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
            objc_setAssociatedObject(self, "gif.net.maker", nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        });
    }
}

- (NetState)state {
    NSNumber *state = objc_getAssociatedObject(self, "obj.net.state");
    return state.integerValue;
}

@end

#pragma mark - 通用规则
@implementation RequestNormal (General)

- (void)backToLogin:(NSString *)message {
    // 返回登录界面
    //清除登录状态

    LoginViewController *loginController = [[LoginViewController alloc]init];
    UINavigationController *navLoginVc = [[UINavigationController alloc]initWithRootViewController:loginController];

    [UIApplication sharedApplication].windows[0].rootViewController = navLoginVc;



    // 提示在其他位置登录
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];

    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil]];

    [navLoginVc showDetailViewController:alert sender:nil];
}

- (ShowStateGIF)showGIF {
    __weak typeof(self) weakSelf = self;
    return ^(int style) {
        GIFMaker *maker = [GIFMaker new];
        maker->_request = self;
        maker->_style = style;
        maker->_color = [UIColor whiteColor];
        weakSelf.blockMap[@"GIFMaker"] = maker;
        return maker;
    };
}

- (Complete)onResponse {
    __weak typeof(self) weakSelf = self;
    return ^(dispatch_block_t responseBlock) {
        weakSelf.blockMap[@"onResponse"] = responseBlock;//[completeBlock copy];
        return weakSelf;
    };
}

- (Complete)onComplete {
    __weak typeof(self) weakSelf = self;
    return ^(dispatch_block_t completeBlock) {
        weakSelf.blockMap[@"onComplete"] = completeBlock;//[completeBlock copy];
        return weakSelf;
    };
}

- (Failure)onFailure {
    __weak typeof(self) weakSelf = self;
    return ^(OnFailure failureBlock) {
        weakSelf.blockMap[@"onFailure"] = failureBlock;//[failureBlock copy];
        return weakSelf;
    };
}

- (nonnull NSURLSessionTask *)onSuccess:(nonnull NSObject *)target selector:(nonnull SEL)selector {
    __weak NSObject *weakTarget = target;
    return [self onSuccess:^(id  _Nonnull response) {
        [weakTarget performSelector:selector withObject:response afterDelay:0];
    }];
}

- (nonnull NSURLSessionTask *)onTWSuccess:(OnSuccess _Nonnull)successBlock {
    __block OnSuccess onSuccess = [successBlock copy];
    
    __block GIFMaker *maker = self.blockMap[@"GIFMaker"];
    if (maker != nil) {
        self.blockMap[@"GIFMaker"] = nil;
        maker->_obj.maker = maker;
        maker->_obj.state = NetStateLoading;

        ReloadMaker *reloader = maker->_reloadMaker;
        if (reloader != nil) {
            reloader->_mask = maker->_mask;
            reloader->_text = maker->_text;
            reloader->_color = maker->_color;
            reloader->_style = maker->_style;

            maker->_obj.reloader = reloader;
        }
    }
    return [self commit:^(ResponseNormal * response) {
        
        RequestNormal *request = response.request;
        
        NSObject *pageObj;
        if (maker != nil) {
            pageObj = maker->_obj;
        }
  
        dispatch_block_t onResponse = request.blockMap[@"onResponse"];
        dispatch_block_t onComplete = request.blockMap[@"onComplete"];
        if (onResponse) {
            onResponse();
        }
        if (onComplete) {
            // 完成回调 (不论成功失败) 加入 queue 是为了在 return 之后执行
            dispatch_async(dispatch_get_main_queue(), onComplete);
            
        }
        
        if (maker != nil) {
            dispatch_async(dispatch_get_main_queue(), ^{
                pageObj.state = NetStateComplete;
            });
        }

        
        OnFailure onFailure = request.blockMap[@"onFailure"];
        if (onFailure == nil) {
            onFailure = ^(NSError *error) {
                
//                AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
//                
//                [appDelegate RequestErrorInfo:error];
            };
        }
        
        NSData *data = [response.request valueForKey:@"POSTParams"];
        // 如果网络失败
        NSLog(@"onSuccess:--->%@&%@", response.urlRequest.URL, [NSString stringWithData:data encoding:NSUTF8StringEncoding]);
        if (response.error) {
            if (response.error.code != -999) {
                NSLog(@"%@",response.error);
                onFailure(response.error);
            }
            return;
        }
        NSError *error;
        id result = [NSJSONSerialization JSONObjectWithData:response.data options:NSJSONReadingAllowFragments error:&error];
        
        NSDictionary *resultData;
        if (IS_DES) {
            NSString *desStr = [NSString DES_DecryptWithText:result[@"data"]];
            resultData = [LCdes decodeFromPercentEscapeStringTwo:desStr];
        }else{
             resultData = [LCdes decodeFromPercentEscapeStringTwo: Format(@"%@",result[@"data"] ?:@"")];
        }
        // 如果 JSON 解析失败
        if (result == nil) {
            [pageObj showNetFailReloadViewOnRequest:request onSuccess:onSuccess];
            onFailure(error);
            return;
        }
        
        // 如果服务端返回错误
        if ([resultData[@"status"] isEqualToString:@"0"]) {
            [pageObj showNetFailReloadViewOnRequest:request onSuccess:onSuccess];
            onFailure(error);
            return;
        }
        //判断是否为超时和单点登录
        if ([resultData[@"result"] isEqualToString:@"sessionexpired"]) {

#warning 调用自动登录接口
            [Network.autoLogin
             .onFailure(^(NSError * error) {
                [request backToLogin:@"请重新登录"];

            })onSuccess:^(id _Nonnull response) {
                //重试本次参数获取
                [request onSuccess:onSuccess];

            }].priority = NSURLSessionTaskPriorityHigh;

            return;

        }

        if ([resultData[@"result"] isEqualToString:@"sessionmore"] || [resultData[@"result"] isEqualToString:@"sessionout"]) {
            NSLog(@"%@",result);
            [request backToLogin:@"已在其他设备登录"];
            return;
        }
        NSLog(@"%@",result);
        pageObj.reloader = nil;

        onSuccess(result);
    }];
}

- (nonnull NSURLSessionTask *)onSuccess:(OnSuccess _Nonnull)successBlock {
    __block OnSuccess onSuccess = [successBlock copy];

    __block GIFMaker *maker = self.blockMap[@"GIFMaker"];
    if (maker != nil) {
        self.blockMap[@"GIFMaker"] = nil;
        maker->_obj.maker = maker;
        maker->_obj.state = NetStateLoading;
        
        ReloadMaker *reloader = maker->_reloadMaker;
        if (reloader != nil) {
            reloader->_mask = maker->_mask;
            reloader->_text = maker->_text;
            reloader->_color = maker->_color;
            reloader->_style = maker->_style;
            
            maker->_obj.reloader = reloader;
        }
    }
    return [self commit:^(ResponseNormal * response) {
        
        RequestNormal *request = response.request;
        
        NSObject *pageObj;
        if (maker != nil) {
            pageObj = maker->_obj;
        }

        dispatch_block_t onResponse = request.blockMap[@"onResponse"];
        dispatch_block_t onComplete = request.blockMap[@"onComplete"];
        if (onResponse) {
            onResponse();
        }
        if (onComplete) {
            // 完成回调 (不论成功失败) 加入 queue 是为了在 return 之后执行
            dispatch_async(dispatch_get_main_queue(), onComplete);
            
        }
        if (maker != nil) {
            dispatch_async(dispatch_get_main_queue(), ^{
                pageObj.state = NetStateComplete;
            });
        }

        
        OnFailure onFailure = request.blockMap[@"onFailure"];
        if (onFailure == nil) {
            onFailure = ^(NSError *error) {

                
//                AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
//
//                [appDelegate RequestErrorInfo:error];
            };
        }
        
        NSData *data = [response.request valueForKey:@"POSTParams"];
        // 如果网络失败
        NSLog(@"onSuccess:--->%@&%@", response.urlRequest.URL, [NSString stringWithData:data encoding:NSUTF8StringEncoding]);

        if (response.error) {
            if (response.error.code != -999) {
                NSLog(@"%@",response.error);
                [pageObj showNetFailReloadViewOnRequest:request onSuccess:onSuccess];
                onFailure(response.error);
            }
            return;
        }
        NSError *error;
        id result = [NSJSONSerialization JSONObjectWithData:response.data options:NSJSONReadingMutableContainers error:&error];
        // 如果 JSON 解析失败
        if (result == nil) {
            [pageObj showNetFailReloadViewOnRequest:request onSuccess:onSuccess];
            onFailure(error);
            return;
        }
        //NSLog(@"%@",result);
        // 如果服务端返回错误
        if ([result[@"result"] isEqualToString:@"fail"]) {
            [pageObj showNetFailReloadViewOnRequest:request onSuccess:onSuccess];
            onFailure([NSError errorWithDomain:result[@"desc"] code:-1000 userInfo:result]);
            return;
        }
        
        if ([result[@"result"] isEqualToString:@"sessionexpired"]) {
            
#warning 调用自动登录接口
//            [Network.autoLogin
//             .onFailure(^(NSError * error) {
//                [request backToLogin:@"请重新登录"];
//                //[weakSelf backToLogin:@"请重新登录"];
//            })onSuccess:^(id _Nonnull response) {
//                //重试本次参数获取
//                [request onSuccess:onSuccess];
//
//            }].priority = NSURLSessionTaskPriorityHigh;
            
            return;
           
        }
        
        if ([result[@"result"] isEqualToString:@"sessionmore"] || [result[@"result"] isEqualToString:@"sessionout"]) {
            NSLog(@"%@",result);
//            [request backToLogin:@"已在其他设备登录"];
            return;
        }
        // 如果服务端返回失败
        NSLog(@"%@",result);
        if ([result[@"result"] intValue] != 1) {
            [pageObj showNetFailReloadViewOnRequest:request onSuccess:onSuccess];
//            onFailure([NSError errorWithDomain:result[@"desc"] code:-1001 userInfo:result]);
            onFailure(error);
            return;
        }
        NSLog(@"%@",result);
        
        pageObj.reloader = nil;
        
        NSData *postData = [response.request valueForKey:@"POSTParams"];
        NSString *params = [NSString stringWithData:postData encoding:NSUTF8StringEncoding];
        // 如果服务端返回成功
        NSLog(@"onSuccess:--->%@?%@", response.urlRequest.URL, params);
        onSuccess(result);
    }];
}

#pragma mark - 审核相关
- (nonnull NSURLSessionTask *)onAPPLESuccess:(OnSuccess _Nonnull)successBlock {
    __block OnSuccess onSuccess = [successBlock copy];
    
    __block GIFMaker *maker = self.blockMap[@"GIFMaker"];
    if (maker != nil) {
        self.blockMap[@"GIFMaker"] = nil;
        maker->_obj.maker = maker;
        maker->_obj.state = NetStateLoading;
        
        ReloadMaker *reloader = maker->_reloadMaker;
        if (reloader != nil) {
            reloader->_mask = maker->_mask;
            reloader->_text = maker->_text;
            reloader->_color = maker->_color;
            reloader->_style = maker->_style;
            
            maker->_obj.reloader = reloader;
        }
    }
    return [self commit:^(ResponseNormal * response) {
        
        RequestNormal *request = response.request;
        
        NSObject *pageObj;
        if (maker != nil) {
            pageObj = maker->_obj;
        }
        
        dispatch_block_t onResponse = request.blockMap[@"onResponse"];
        dispatch_block_t onComplete = request.blockMap[@"onComplete"];
        if (onResponse) {
            onResponse();
        }
        if (onComplete) {
            // 完成回调 (不论成功失败) 加入 queue 是为了在 return 之后执行
            dispatch_async(dispatch_get_main_queue(), onComplete);
            
        }
        if (maker != nil) {
            dispatch_async(dispatch_get_main_queue(), ^{
                pageObj.state = NetStateComplete;
            });
        }
        
        
        OnFailure onFailure = request.blockMap[@"onFailure"];
        if (onFailure == nil) {
            onFailure = ^(NSError *error) {
                
            };
        }
        
        NSData *data = [response.request valueForKey:@"POSTParams"];
        // 如果网络失败
        NSLog(@"onSuccess:--->%@&%@", response.urlRequest.URL, [NSString stringWithData:data encoding:NSUTF8StringEncoding]);
        
        if (response.error) {
            if (response.error.code != -999) {
                NSLog(@"%@",response.error);
                [pageObj showNetFailReloadViewOnRequest:request onSuccess:onSuccess];
                onFailure(response.error);
            }
            return;
        }
        NSError *error;
        id result = [NSJSONSerialization JSONObjectWithData:response.data options:NSJSONReadingMutableContainers error:&error];

        NSData *postData = [response.request valueForKey:@"POSTParams"];
        NSString *params = [NSString stringWithData:postData encoding:NSUTF8StringEncoding];
        // 如果服务端返回成功

        onSuccess(result);
    }];
}






@end
